package educrypt.gui.components;

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;

import educrypt.gui.util.GuiUtil;
import educrypt.gui.view.AnalysisDetailView;
import educrypt.gui.view.DatabaseView;
import educrypt.gui.view.EducryptFileChooserView;
import educrypt.i18n.Messages;
import educrypt.resources.EduCryptResources;

public class DatabasePanel extends EducryptPanel implements DatabaseView {

	private static final long serialVersionUID = 3298476410758291486L;

	private JButton btnRemoveText, btnRemoveAnalysis, btnAnalysisDetail,
			btnImportDatabase, btnExportDatabase, btnTextTypeEditor,
			btnTextLanguageEditor, btnKeywordEditor, btnAlphabetEditor;
	private EducryptFileChooser saveFileDialog, loadFileDialog;
	private JTable textTable, analysisTable;

	private AnalysisDetailDialog analysisDetailDialog;
	private JLabel lblOtherEditor;

	public DatabasePanel() {
		this.setSize(740, 650);
		this.setPreferredSize(this.getSize());
		setLayout(null);

		JLabel lblTextAnalysisEditor = new JLabel(
				Messages.getString("guiAnalysisEditor"));
		lblTextAnalysisEditor.setFont(new Font("Tahoma", Font.BOLD, 15));
		lblTextAnalysisEditor.setBounds(26, 11, 249, 19);
		add(lblTextAnalysisEditor);

		JLabel lblTexts = new JLabel(Messages.getString("guiTexts"));
		lblTexts.setBounds(26, 41, 70, 14);
		add(lblTexts);

		JLabel lblAnalysis = new JLabel(Messages.getString("guiAnalysis"));
		lblAnalysis.setBounds(477, 41, 77, 14);
		add(lblAnalysis);

		ImageIcon removeIcon = new ImageIcon(
				EduCryptResources.getImageURL("remove24color.png"));

		btnRemoveText = new JButton(removeIcon);
		btnRemoveText.setBounds(413, 63, 28, 28);
		add(btnRemoveText);

		btnRemoveAnalysis = new JButton(removeIcon);
		btnRemoveAnalysis.setBounds(688, 94, 28, 28);
		add(btnRemoveAnalysis);

		ImageIcon detailIcon = new ImageIcon(
				EduCryptResources.getImageURL("preview24.png"));

		btnAnalysisDetail = new JButton(detailIcon);
		btnAnalysisDetail.setBounds(688, 63, 28, 28);
		add(btnAnalysisDetail);

		btnImportDatabase = new JButton(Messages.getString("guiImportDatabase"));
		btnImportDatabase.setBounds(169, 575, 128, 37);
		add(btnImportDatabase);

		btnExportDatabase = new JButton(Messages.getString("guiExportDatabase"));
		btnExportDatabase.setBounds(450, 575, 128, 37);
		add(btnExportDatabase);

		JLabel lblImportExportDB = new JLabel(
				Messages.getString("guiImportExport"));
		lblImportExportDB.setFont(new Font("Tahoma", Font.BOLD, 15));
		lblImportExportDB.setBounds(26, 535, 347, 19);
		add(lblImportExportDB);

		JSeparator separator = new JSeparator();
		separator.setBounds(190, 400, 359, 1);
		add(separator);

		saveFileDialog = new EducryptFileChooser(btnExportDatabase);
		saveFileDialog.setSqlMode();
		loadFileDialog = new EducryptFileChooser(btnImportDatabase);
		loadFileDialog.setSqlMode();

		initializeTables();

		analysisDetailDialog = new AnalysisDetailDialog(
				GuiUtil.findParentFrame(this));

		JSeparator separator_1 = new JSeparator();
		separator_1.setBounds(190, 520, 359, 1);
		add(separator_1);

		btnTextTypeEditor = new JButton(Messages.getString("guiTextTypeEditor"));
		btnTextTypeEditor.setBounds(26, 460, 166, 37);
		add(btnTextTypeEditor);

		btnTextLanguageEditor = new JButton(
				Messages.getString("guiTextLanguageEditor"));
		btnTextLanguageEditor.setBounds(200, 460, 166, 37);
		add(btnTextLanguageEditor);

		btnKeywordEditor = new JButton(Messages.getString("guiKeywordEditor"));
		btnKeywordEditor.setBounds(548, 460, 166, 37);
		add(btnKeywordEditor);

		btnAlphabetEditor = new JButton(Messages.getString("guiAlphabetEditor"));
		btnAlphabetEditor.setBounds(374, 460, 166, 37);
		add(btnAlphabetEditor);

		lblOtherEditor = new JLabel(Messages.getString("guiOtherEditors")); //$NON-NLS-1$
		lblOtherEditor.setFont(new Font("Tahoma", Font.BOLD, 15));
		lblOtherEditor.setBounds(26, 417, 249, 19);
		add(lblOtherEditor);
	}

	private void initializeTables() {
		// Text
		JScrollPane scrollPaneTexts = new JScrollPane();
		scrollPaneTexts.setBounds(26, 63, 384, 310);
		add(scrollPaneTexts);

		TextAnalysisTableModel textTableModel = new TextAnalysisTableModel();
		textTableModel.setColumnNames(new String[] {
				Messages.getString("guiName"), Messages.getString("guiType"),
				Messages.getString("guiLanguage") });

		textTable = new JTable(textTableModel);
		scrollPaneTexts.setViewportView(textTable);

		textTable.setColumnSelectionAllowed(false);
		textTable.setRowSelectionAllowed(true);
		textTable.setCellSelectionEnabled(false);

		textTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

		DefaultTableCellRenderer dtcrText = new TextAnalysisDefaultTableCellRenderer();
		textTable.setDefaultRenderer(Object.class, dtcrText);

		JScrollPane scrollPaneAnalysis = new JScrollPane();
		scrollPaneAnalysis.setBounds(467, 63, 218, 310);
		add(scrollPaneAnalysis);

		TextAnalysisTableModel analysisTableModel = new TextAnalysisTableModel();
		analysisTableModel.setColumnNames(new String[] {
				Messages.getString("guiAlphabet"),
				Messages.getString("guiNgramSize") });

		// Analysis
		analysisTable = new JTable(analysisTableModel);
		scrollPaneAnalysis.setViewportView(analysisTable);

		analysisTable.setColumnSelectionAllowed(false);
		analysisTable.setRowSelectionAllowed(true);
		analysisTable.setCellSelectionEnabled(false);

		analysisTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

		DefaultTableCellRenderer dtcrAnalysis = new TextAnalysisDefaultTableCellRenderer();
		analysisTable.setDefaultRenderer(Object.class, dtcrAnalysis);
	}

	@Override
	public void addListener(ActionListener ctr) {
		// Text / Analysis editor
		btnRemoveText.setActionCommand(REMOVE_TEXT);
		btnRemoveText.addActionListener(ctr);
		btnRemoveAnalysis.setActionCommand(REMOVE_ANALYSIS);
		btnRemoveAnalysis.addActionListener(ctr);
		btnAnalysisDetail.setActionCommand(DETAIL_ANALYSIS);
		textTable.getSelectionModel().addListSelectionListener(
				(ListSelectionListener) ctr);
		analysisDetailDialog.addListener(ctr);

		// Other editors
		btnTextTypeEditor.setActionCommand(EDITOR_TEXT_TYPES);
		btnTextTypeEditor.addActionListener(ctr);
		btnTextLanguageEditor.setActionCommand(EDITOR_TEXT_LANGUAGES);
		btnTextLanguageEditor.addActionListener(ctr);
		btnAlphabetEditor.setActionCommand(EDITOR_ALPHABETS);
		btnAlphabetEditor.addActionListener(ctr);
		btnKeywordEditor.setActionCommand(EDITOR_KEYWORDS);
		btnKeywordEditor.addActionListener(ctr);

		// Import / Export database
		btnAnalysisDetail.addActionListener(ctr);
		btnImportDatabase.setActionCommand(IMPORT_DB);
		btnImportDatabase.addActionListener(ctr);
		btnExportDatabase.setActionCommand(EXPORT_DB);
		btnExportDatabase.addActionListener(ctr);
		saveFileDialog.addListener(ctr);
		loadFileDialog.addListener(ctr);
	}

	@Override
	public EducryptFileChooserView getSaveDialog() {
		return saveFileDialog;
	}

	@Override
	public EducryptFileChooserView getLoadDialog() {
		return loadFileDialog;
	}

	@Override
	public int showImportConfirmation() {
		return GuiUtil.showQuestionDialog(
				this,
				Messages.getString("msgContinueOperation"),
				Messages.getString("msgDBImport") + ", "
						+ Messages.getString("msgContinueOperation"));
	}

	@Override
	public void showTextTableValues(List<List<String>> values) {
		TextAnalysisTableModel model = (TextAnalysisTableModel) textTable
				.getModel();

		model.removeRows();

		for (List<String> row : values) {
			model.addRow(row);
		}
	}

	@Override
	public void removeTextTableValues() {
		TextAnalysisTableModel model = (TextAnalysisTableModel) textTable
				.getModel();

		model.removeRows();
	}

	@Override
	public void removeSelectedTextValue() {
		TextAnalysisTableModel model = (TextAnalysisTableModel) textTable
				.getModel();
		model.removeRow(textTable.getSelectedRow());
	}

	@Override
	public int getSelectedText() {
		return textTable.getSelectedRow();
	}

	@Override
	public void showAnalysisTableValues(List<List<String>> values) {
		TextAnalysisTableModel model = (TextAnalysisTableModel) analysisTable
				.getModel();

		model.removeRows();

		for (List<String> row : values) {
			model.addRow(row);
		}
	}

	@Override
	public void removeAnalysisTableValues() {
		TextAnalysisTableModel model = (TextAnalysisTableModel) analysisTable
				.getModel();

		model.removeRows();
	}

	@Override
	public void removeSelectedAnalysisValue() {
		TextAnalysisTableModel model = (TextAnalysisTableModel) analysisTable
				.getModel();
		model.removeRow(analysisTable.getSelectedRow());
	}

	@Override
	public int getSelectedAnalysis() {
		return analysisTable.getSelectedRow();
	}

	@Override
	public void showAnalysisDetail() {
		analysisDetailDialog.open(this);
	}

	class TextAnalysisTableModel extends AbstractTableModel {

		private static final long serialVersionUID = -7817793250686884154L;

		private String[] columnNames;

		private List<List<String>> data = new ArrayList<List<String>>();

		public void setColumnNames(String[] columnNames) {
			this.columnNames = columnNames;
		}

		public int getColumnCount() {
			return columnNames.length;
		}

		public int getRowCount() {
			return data.size();
		}

		public String getColumnName(int col) {
			return columnNames[col];
		}

		public Object getValueAt(int row, int col) {
			return data.get(row).get(col);
		}

		public void removeRow(int i) {
			int rowCount = data.size();
			if (rowCount > 0 && i >= 0 && i < rowCount) {
				data.remove(i);
				fireTableRowsDeleted(i, i);
			}
		}

		public void removeRows() {
			int rowCount = data.size();
			if (rowCount > 0) {
				int lastRow = rowCount - 1;
				data.clear();
				fireTableRowsDeleted(0, lastRow);
			}
		}

		/*
		 * Don't need to implement this method unless your table's data can
		 * change.
		 */
		public void setValueAt(String value, int row, int col) {
			while (data.size() < row + 1) {
				data.add(new ArrayList<String>());
			}
			List<String> columns = data.get(row);
			while (columns.size() < col + 1) {
				columns.add(new String());
			}
			columns.set(col, value);

			fireTableCellUpdated(row, col);

		}

		public void addRow(List<String> values) {
			data.add(values);
			fireTableDataChanged();
		}
	}

	class TextAnalysisDefaultTableCellRenderer extends DefaultTableCellRenderer {

		private final Color defaultBgColor;

		public TextAnalysisDefaultTableCellRenderer() {
			defaultBgColor = this.getBackground();
			setHorizontalAlignment(DefaultTableCellRenderer.CENTER);
		}

		private static final long serialVersionUID = -7011919151633346815L;

		public Component getTableCellRendererComponent(JTable table,
				Object value, boolean isSelected, boolean hasFocus, int row,
				int col) {
			/*
			 * Implementation Note : It is important that no "new" be present in
			 * this implementation (excluding exceptions): if the table is
			 * large, then a large number of objects would be created during
			 * rendering.
			 */
			super.getTableCellRendererComponent(table, value, isSelected,
					hasFocus, row, col);

			if (table.isRowSelected(row)) {
				setBackground(Color.ORANGE);
			} else {
				setBackground(defaultBgColor);
			}
			return this;
		}
	}

	@Override
	public AnalysisDetailView getAnalyisisDetailDialog() {
		return analysisDetailDialog;
	}
}
